﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class EnemySight : MonoBehaviour
{
    private List<Vector3> tri = new List<Vector3>();

    public float sightAngle;
    public float stepDegree = 20;
    public float sightDistance = 4;
    void Start()
    {
        GetComponent<SphereCollider>().radius = sightDistance;
        SetSubdivisionTriangles(Mathf.FloorToInt(sightAngle / stepDegree), -sightAngle / 2, sightAngle / 2);
        DrawSight();
    }
    void Update()
    {

    }


    void OnTriggerStay(Collider other)
    {

        if (other.transform.tag == "Player")
        {
            if (Calculator.IsInSight(this.gameObject, other.transform.position, sightAngle))
            {


                if (Physics.Raycast(this.transform.position, other.transform.position - this.transform.position))
                {

                    this.transform.parent.GetComponent<EnemyAI>().FoundPlayer(other.transform.position);

                }

            }

        }
        if (other.transform.tag == "Wall")
        {



            tri.Clear();
            //Point[] points = SetVertexStatus(GetWallVertex(other.transform));
            //AddTriangle(this.transform.InverseTransformPoint(points[0].point), this.transform.InverseTransformPoint(points[1].point));
            //AddTriangle(this.transform.InverseTransformPoint(points[1].point), this.transform.InverseTransformPoint(points[2].point));
            //AddTriangle(this.transform.InverseTransformPoint(points[2].point), this.transform.InverseTransformPoint(points[3].point));
            //AddTriangle(this.transform.InverseTransformPoint(points[3].point), this.transform.InverseTransformPoint(points[0].point));
            //DrawSight();
            RaycastHit hit = new RaycastHit();
            RaycastHit nextHit;
            bool isBlocked = false;
            bool isNextBlocked = false;
            for (var i = -sightAngle / 2; i < sightAngle / 2; i += stepDegree)
            {
                if (i == -sightAngle / 2)
                {
                    isBlocked = Physics.Raycast(this.transform.position, Calculator.RotateTo(this.transform.forward, new Vector3(0, i, 0)), out hit, sightDistance, LayerMask.GetMask("Wall"));
                }
                isNextBlocked = Physics.Raycast(this.transform.position, Calculator.RotateTo(this.transform.forward, new Vector3(0, i + stepDegree, 0)), out nextHit, sightDistance, LayerMask.GetMask("Wall"));
                if (isBlocked)
                {
                    if (isNextBlocked)
                    {
                        AddTriangle(this.transform.InverseTransformPoint(hit.point), this.transform.InverseTransformPoint(nextHit.point));
                    }
                    else
                    {
                        AddTriangle(Calculator.RotateTo(this.transform.forward * sightDistance, new Vector3(0, i, 0)), Calculator.RotateTo(this.transform.forward * sightDistance, new Vector3(0, i + stepDegree, 0)));
                        //AddTriangle(this.transform.InverseTransformPoint(hit.point), Calculator.RotateTo(this.transform.InverseTransformPoint(hit.point), new Vector3(0, stepDegree, 0)));
                    }



                }
                else
                {
                    AddTriangle(Calculator.RotateTo(this.transform.forward * sightDistance, new Vector3(0, i, 0)), Calculator.RotateTo(this.transform.forward * sightDistance, new Vector3(0, i + stepDegree, 0)));
                }
                isBlocked = isNextBlocked;
                hit = nextHit;

            }
            DrawSight();
        }
        if (other.transform.tag == "EnemyBody")
        {
            if (Calculator.IsInSight(this.gameObject, other.transform.position, sightAngle))
            {
                if (other.transform.parent.GetComponent<Enemy>().isDead)
                {
                    if (!other.transform.parent.GetComponent<Enemy>().isDeadFound)
                    {
                        other.transform.parent.GetComponent<Enemy>().isDeadFound = true;
                        this.transform.parent.GetComponent<EnemyAI>().FoundBody(other.transform.position);
                    }
                    
                }
            }
        }


    }
    void OnTriggerExit(Collider other)
    {
        tri.Clear();
        SetSubdivisionTriangles(Mathf.FloorToInt(sightAngle / stepDegree), -sightAngle / 2, sightAngle / 2);
        DrawSight();
    }
    //Point[] GetWallVertex(Transform tran)
    //{
    //    var vertexs = new Point[4];
    //    int[] a = { 1, 1, -1, -1 };
    //    int[] b = { 1, -1, -1, 1 };
    //    for (int i = 0; i < 4; i++)
    //    {
    //        var pointRota = tran.rotation * new Vector3(a[i] * tran.localScale.x / 2, tran.localScale.y / 2, b[i] * tran.localScale.z / 2);
    //        var vertex = new Vector3(tran.position.x, 0.5f, tran.position.z) + new Vector3(pointRota.x, 0.5f, pointRota.z);
    //        vertexs[i] = new Point();
    //        vertexs[i].point = vertex;
    //    }
    //    return vertexs;
    //}
    //Point[] SetVertexStatus(Point[] vertexs)
    //{
    //    for (var i = 0; i < 4; i++)
    //    {
    //        vertexs[i].distance = Vector3.Distance(vertexs[i].point, this.transform.position);
    //        if (vertexs[i].distance <= sightDistance)
    //        {
    //            vertexs[i].distanceStatus = 1;
    //        }
    //        else
    //        {
    //            vertexs[i].distanceStatus = 2;
    //        }
    //        vertexs[i].angle = Calculator.AngleInSight(this.transform, vertexs[i].point);
    //        if (Calculator.IsInSight(this.gameObject, vertexs[i].point, sightAngle))
    //        {
    //            vertexs[i].angleStatus = 1;
    //        }
    //        else
    //        {
    //            vertexs[i].angleStatus = 2;
    //        }
    //    }
    //    return vertexs;
    //}
    void SetSubdivisionTriangles(int subdivision, float from, float to)
    {
        for (var i = from; i < to; i += (to - from) / subdivision)
        {
            AddTriangle(Calculator.RotateTo(Vector3.forward * sightDistance, new Vector3(0, i, 0)), Calculator.RotateTo(Vector3.forward * sightDistance, new Vector3(0, i + (to - from) / subdivision, 0)));
        }

    }
    void AddTriangle(Vector3 vec1, Vector3 vec2)
    {
        tri.Add(new Vector3());
        tri.Add(vec1);
        tri.Add(vec2);
    }
    void DrawSight()
    {
        Vector3[] newVertices;
        Vector2[] newUV;
        int[] newTriangles;
        newVertices = new Vector3[tri.Count];
        newUV = new Vector2[tri.Count];
        newTriangles = new int[tri.Count];
        tri.CopyTo(newVertices);
        for (int i = 0; i < newTriangles.Length; i++)
        {
            newTriangles[i] = i;
        }
        Mesh mesh = GetComponent<MeshFilter>().mesh;
        mesh.Clear();
        mesh.vertices = newVertices;
        mesh.uv = newUV;
        mesh.triangles = newTriangles;
    }

}
public class Point
{
    public Vector3 point = new Vector3();
    public int angleStatus = 0; // 0 未判断 1 在内 2 在外
    public int distanceStatus = 0; // 0 未判断 1 在内 2 在外
    public float distance = 0;
    public float angle;
    public Point()
    {

    }
}